(function () {
    function __rex(value, errorMsg, rex){
        if (!(rex.test(value))) {
            return errorMsg;
        }
    }
    /*********************** 策略对象 **************************/
    var strategies = {
        //非空
        isNonEmpty: function (value, errorMsg) {
            if (value == undefined || value == null) {
                return errorMsg;
            } else if (value == "" || value.replace(/\s+/g, "") == "" || value.length < 1) {
                return errorMsg;
            }
        },
        //最小长度
        minLength: function (value, length, errorMsg) {
            if (value.length < length) {
                return errorMsg;
            }
        },
        //手机号
        isMobile: function(value, errorMsg){return __rex(value, errorMsg, /^1(3|4|5|7|8)\d{9}$/);},
        //只能是汉字
        isCn: function(value, errorMsg){return __rex(value, errorMsg, /^[\u0391-\uFFE5]+$/);},
        //只能是英文字母
        isEn: function(value, errorMsg){return __rex(value, errorMsg, /^[a-zA-Z]*$/);},
        //只能是数字
        isNumber: function(value, errorMsg){return __rex(value, errorMsg, /^[0-9]+$/);},
        //只能是字母和数字
        isEnNumber: function(value, errorMsg){return __rex(value, errorMsg, /^[0-9a-zA-Z]*$/);},
        //不能包含特殊字符
        isNokeyword: function (value, errorMsg) {
            var flag = true;
            var arr = arguments[2];
            for (var i = 0; i < arr.length; i++) {
                var r = new RegExp(arr[i], "gim");
                if (r.test(value)) {
                    flag = false;
                    break;
                }
            }
            if (!flag) {
                return errorMsg;
            }
        },
        //比较2个值是否相等
        isEqual: function (value, errorMsg) {
            if (value != arguments[2]) {
                return errorMsg;
            }
        },
        //只能是邮箱
        isEmali: function(value, errorMsg){return __rex(value, errorMsg, /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/)},
        //只能是身份证
        isIdCard: function (value, errorMsg) {
            var checkFlag = new clsIDCard(value);
            if (!checkFlag.IsValid()) {
                return errorMsg;
            }
        },
        //验证日期格式是否正确，格式：YYYY-MM-DD，注意这里不验证年月日数字，仅格式
        isYMD: function (value, errorMsg) {
            var str = value.replace(/\s+/g, "");
            var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/;
            var r = str.match(reg);
            if (r == null) {
                return errorMsg;
            }
        },
        //验证时间是否正确，格式：hh:mm:ss，注意这里不验证数字，仅格式
        isTime: function(value, errorMsg){return __rex(value, errorMsg, /^((20|21|22|23|[0-1]\d)\:[0-5][0-9])(\:[0-5][0-9])?$/)},
        //验证日期时间格式是否正确，格式：YYYY-MM-DD hh:mm:ss，注意这里不验证数字，仅格式
        isDate: function (value, errorMsg) {
            var str = value.trim();
            var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/;
            var r = str.match(reg);
            if (r == null) {
                return errorMsg;
            }
        },
        //只能是整数
        isInt: function(value, errorMsg){return __rex(value, errorMsg, /^[-+]?\d*$/)},
        //只能是双精度数字
        isDoublePrecision: function(value, errorMsg){return __rex(value, errorMsg, /^[-\+]?\d+(\.\d+)?$/)},
        //只能是邮政编码
        isZipCode: function(value, errorMsg){return __rex(value, errorMsg, /^\d{6}$/)},
        //只能是url地址
        isUrl: function(value, errorMsg){return __rex(value, errorMsg, /^http(s)?:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/)},
        //只能是qq
        isQQ: function(value, errorMsg){return __rex(value, errorMsg, /^[1-9]\d{4,8}$/)},
        //只能是ip地址
        isIP: function(value, errorMsg){return __rex(value, errorMsg, /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/)},
        //只能是正数
        isPositiveNumber: function(value, errorMsg){return __rex(value, errorMsg, /^\d+$/)},
        //只能是只能中英文，数字，下划线，减号
        isUserName: function(value, errorMsg){return __rex(value, errorMsg, /^[\u4e00-\u9fa5A-Za-z0-9-_]*$/)}
    };
    /*********************** 通用逻辑，效验类 **************************/
    var Validator = function () {
        this.cache = [];
    };
    //用于添加规则
    Validator.prototype.add = function (dom, rules, param) {
        var self = this;
        for (var i = 0, rule; rule = rules[i++];) {
            (function (rule) {
                var strategyAry = rule.strategy.split(':');
                var errorMsg = rule.errorMsg;
                self.cache.push(function () {
                    var strategy = strategyAry.shift();
                    strategyAry.unshift(dom.value);
                    strategyAry.push(errorMsg);
                    if (param instanceof Array) { strategyAry.push(param); }
                    if (param instanceof Object) { strategyAry.push(param.value); }
                    return strategies[strategy].apply(dom, strategyAry);
                });
            })(rule)
        }
    };
    //用于效验规则
    Validator.prototype.start = function (fn) {
        for (var i = 0, fn; fn = this.cache[i++];) {
            var errorMsg = fn();
            if (errorMsg) {
                return errorMsg;
            }
        }
    };

    window.Validator = Validator;
})();